package net.omegachess.classes
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.core.Container;
	import mx.core.IFlexDisplayObject;
	import mx.utils.ObjectUtil;
	
	import net.omegachess.classes.pieces.Bishop;
	import net.omegachess.classes.pieces.Champion;
	import net.omegachess.classes.pieces.Hole;
	import net.omegachess.classes.pieces.King;
	import net.omegachess.classes.pieces.Knight;
	import net.omegachess.classes.pieces.Pawn;
	import net.omegachess.classes.pieces.Piece;
	import net.omegachess.classes.pieces.Queen;
	import net.omegachess.classes.pieces.Rook;
	import net.omegachess.classes.pieces.Wizard;
	import net.omegachess.components.Cell;
	import net.omegachess.events.CellSelectedEvent;
	import net.omegachess.events.MoveAcceptedEvent;

	[RemoteClass]
	public class Board extends EventDispatcher
	{
		private var whoseMove : Number = Piece.ALIGNMENT_WHITE;
		private var board : Array;
		private var display : Container;
		
		private var whiteKing : Cell = null;
		private var blackKing : Cell = null;
		
		public function Board(d : Container = null, target:IEventDispatcher=null) 
		{					
			super(target);			
			
			if(d != null) {
				board = new Array();
				display = d;										
				
				for(var r : Number = 0; r < 12; r++) {
					for(var f : Number = 0; f < 12; f++) {
						var c : Cell = new Cell();
							c.rank = r;
							c.file = f;
							//c.piece = new Hole();
							c.piece = populateByRankAndFile(r, f);
							c.addEventListener(CellSelectedEvent.CELL_SELECTED, cellSelectedHandler);
						board.push(c);
						
						display.addChild(c);
					}
				}
				
				trace(toOCPN());
			}
		}
	
		public function draw() : void {
			//display.removeAllChildren();
			
			for(var i : Number = 0; i < 144; i++) {
				(board[i] as Cell).draw();
			}
		}
		
		public static const MOVE_STATE_SELECT_PIECE : Number = 1;
		public static const MOVE_STATE_ACCEPT_TARGET : Number = 2;
		
		public var moveState : Number = Board.MOVE_STATE_SELECT_PIECE;
		
		public function cellSelectedHandler( event : CellSelectedEvent ) : void {			
			var cell : Cell = event.cell as Cell;			
			var piece : Piece = cell.piece;
		
			if(moveState == Board.MOVE_STATE_SELECT_PIECE) {
				if(piece.alignment == whoseMove) {
					var cse : CellSelectedEvent = new CellSelectedEvent(cell, CellSelectedEvent.CELL_SELECTED)					
					dispatchEvent(cse);
				}
			} else if(moveState == Board.MOVE_STATE_ACCEPT_TARGET) {
				
			}
									
		}				
		
		public function getPiecesBitboard() : Bitboard {
			
			var bitboard : Bitboard = new Bitboard();
			
			for(var i : Number = 0; i < 12; i ++) {				
				for( var j : Number = 0; j < 12; j ++) {														
					bitboard.setBitAt(getPieceAt(i, j).alignment, i, j);					
				}
			}

			return bitboard;
		} //function getPiecesBitboard
		
		public function getAlignmentBitboard( alignment : Number ) : Bitboard {
			
			var bitboard : Bitboard = new Bitboard();
			
			for(var i : Number = 0; i < 12; i ++) {				
				for( var j : Number = 0; j < 12; j ++) {
					if(getPieceAt(i, j).alignment == alignment) {
						bitboard.setBitAt(1, i, j);				
					}
				}
			}
			
			return bitboard;			
		} //function getAlignmentBitboard
		
		public function getPieceAt( rank : Number, file : Number ) : Piece {
			return (board[rank * 12 + file] as Cell).piece;
		}
		
		public function setPieceAt( piece : Piece, rank : Number, file : Number ) : void {
			(board[rank * 12 + file] as Cell).piece = piece;
		}		
		
		public function alignmentIsInCheck( alignment : Number ) : Boolean {

			return false;
		}
		
		public function alignmentIsInCheckmate( alignment : Number ) : Boolean {
			//exhaustive search:
				//for each piece
					//for each piece's move
						//if the position is not check
							//break out, it's not checkmate
						//otherwise continue
					//must be checkmate
			
			return false;
		}
		
		private function populateByRankAndFile(rank : Number, file : Number) : Piece {
			
			var piece : Piece;
			
			if((rank == 0 && file != 0 && file != 11) ||
				(rank == 11 && file != 0 && file != 11) ||
				(file == 0 && rank != 0 && rank != 11) || 
				(file == 11 && rank != 0 && rank != 11)) {
				piece = new Hole();
				piece.alignment = Piece.ALIGNMENT_HOLE;
			} else if(rank <=2 || rank >=9) {
				if(file == 0 || file == 11) {
					piece = new Wizard();	
				} else if(rank == 2 || rank == 9){
				//	piece = new Pawn();
					piece = new Hole();
					piece.alignment = Piece.ALIGNMENT_NONE;
				} else if(file == 1 || file == 10) {
					piece = new Champion();				
				} else if(file == 2 || file == 9) {
					piece = new Rook();				
				} else if(file == 3 || file == 8) {
					piece = new Knight();
				} else if(file == 4 || file == 7) {
					piece = new Bishop();
				} else if(file == 6) {
					piece = new King();
				} else if(file == 5) {
					piece = new Queen();
				}
			} else {
				piece = new Hole();
				piece.alignment = Piece.ALIGNMENT_NONE;
			}
								
			if((rank < 5) && !(piece is Hole)) {
				piece.alignment = Piece.ALIGNMENT_WHITE;
			} else if((rank > 5) && !(piece is Hole)) {
				piece.alignment = Piece.ALIGNMENT_BLACK;
			}
			
			return piece;
		}
		
		private function getCellsFromBitboard( bitboard : Bitboard ) : Array {
			var r : Array = new Array();
			
			for(var i : Number = 0; i < 12; i ++) {
				for(var j : Number = 0; j < 12; j++) {
					if(bitboard.getBitAt(i, j) != 0) {
						r.push( board[i*12 + j] );
					}
				}
			}
			
			return r;
		}
		
		public function toOCPN() : String {
			
			var ocpn : String = "";
			
			var counter : Number = 0;
			
			for(var r : Number = 0; r < 12; r ++) {
				for(var f : Number = 0; f < 12; f++) {
					var acn : String = (board[r*12 + f] as Cell).piece.acn();
					
					if((r == 0 && f != 0 && f != 11) || (r == 11 && f != 0 && f != 11) || (f == 0 && r != 0 && r != 11) || (f == 11 && r != 0 && r != 11)) {
						//don't include board holes in OCPN
					} else {					
						if((board[r*12 + f] as Cell).piece is Hole) {
							counter ++;
						} else {
							if(counter != 0) {
								ocpn += counter;
								counter = 0;
							}
							ocpn = ocpn + acn;
						}					
					} //else not hole
				}
				
				if(counter != 0) {
					ocpn += counter;
					counter = 0;	
				}
				
				if(r != 11) {
					ocpn += "/"
				}
			}			
			
			return ocpn;
		} //function OCPN

	}
}